package com.smartstate.iot.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.smartstate.iot.config.redis.RedisService;
import com.smartstate.iot.config.web.SpringUtils;
import com.smartstate.iot.entity.IotDataDistribution;
import com.smartstate.iot.entity.TopicLog;
import com.smartstate.iot.mapper.IotDataDistributionMapper;
import com.smartstate.iot.mapper.TopicLogMapper;
import com.smartstate.iot.service.impl.AmmeterMeterServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 数据处理模块
 */
@Slf4j
public class ThreadService implements Runnable {

    @Resource
    RedisTemplate redisTemplate = RedisService.redis;

    String topic;
    String msg;

    public ThreadService(String topic, String msg) {
        this.topic = topic;
        this.msg = msg;
    }

    private String keys = "dataNumber";

    private String[] ratios = {"electricityIA", "electricityIB", "electricityIC", "phaseActivePowerA", "phaseActivePowerB", "phaseActivePowerC",
            "phaseActivePowerA", "activeElectricEnergyIsMeasuredOnce"};

    @Override
    public void run() {
        log.info("-----{}---执行toptic: {} ,消息处理任务mesg:{}-----------", Thread.currentThread().getName(), topic, msg);
        if (StringUtils.isBlank(topic) || StringUtils.isBlank(msg)) {
            log.error("消费消息主题：{}信息不完整！", topic);
            return;
        }
        Map<String, Object> msgDatas = (Map) JSON.parse(msg);

        JSONArray deviceDataArray = (JSONArray) msgDatas.get("devs");
        for (Object tempo : deviceDataArray) {
            JSONObject deviceDatas = (JSONObject) tempo;
            String deviceId = String.valueOf(deviceDatas.get("dev"));
            if (StringUtils.isBlank(deviceId)) {
                log.error("消费消息主题：{}信息缺失设备ID！", topic);
                continue;
            }
            List<JSONObject> itemInfos = (List) deviceDatas.get("d");
            if (CollectionUtils.isEmpty(itemInfos)) {
                log.error("消费消息主题：{}信息缺失设备数据！", topic);
                continue;
            }
            Map<String, Object> currDeviceDatas = new HashMap<>();
            //系数
            for (JSONObject tempItem : itemInfos) {
                String itemName = String.valueOf(tempItem.get("m"));
                String value = String.valueOf(tempItem.get("v"));

                if (Arrays.asList(ratios).contains(itemName)) {
                    String ratio = SpringUtils.getBean(AmmeterMeterServiceImpl.class).getSiteByDeviceId(deviceId);
                    value = new BigDecimal(String.valueOf(tempItem.get("v"))).multiply(new BigDecimal(ratio)).toString();
                }
                currDeviceDatas.put(itemName, value);
            }
            currDeviceDatas.put("type", "正常");
//            String key = null;
            RedisService redisService = SpringUtils.getBean(RedisService.class);
            redisService.setCacheMap(deviceId, currDeviceDatas);
            log.info("消费消息主题：{}信息缓存成功！", topic);

            //            //  判断该数据是否被分发
//            for (Map.Entry<String, Object> entry : currDeviceDatas.entrySet()) {
//                //表中数据未格式为 deviceId.distrubition,这里需要构成iot_data_distribution 表中data_id字段格式
//                key = Lists.newArrayList(deviceId, entry.getKey()).stream().collect(Collectors.joining("."));
//                String value1 = (String) entry.getValue();
//                handout(key, value1);
//            }
        }
    }

    /**
     * 递归跟新redis中的数据
     *
     * @param key
     * @param value
     */
    private void handout(String key, String value) {
        IotDataDistributionMapper dataDistributionMapper = SpringUtils.getBean(IotDataDistributionMapper.class);
        List<IotDataDistribution> mappings = dataDistributionMapper.getMapping(key);

        if (CollectionUtils.isEmpty(mappings)) {
            return;
        }
        RedisService redisService = SpringUtils.getBean(RedisService.class);
        HashMap<String, String> map = new HashMap<>();
        for (IotDataDistribution mapping : mappings) {
            double weight = mapping.getWeight();
            String targetKey = mapping.getDistributionTarget();
            //  TODO  修改数据分发
            int indexOf = targetKey.indexOf(".");
            String mapKey = targetKey.substring(indexOf + 1);
            String newValue = String.valueOf(Double.parseDouble(value) * weight);
            map.put(mapKey, newValue);
//                int index = key.indexOf(".");
            String hashKey = targetKey.substring(0, indexOf);
            //  缓存不带盒子的
            redisService.setCacheMap(hashKey, map);
            //  缓存带盒子的
            String boxKey = "";
            ArrayList<String> keys = getKeys();
            for (String s : keys) {
                if (s.endsWith(hashKey)) {
                    boxKey = s;
                    break;
                }
            }
            redisService.setCacheMap(boxKey, map);
            handout(targetKey, newValue);
        }
    }

    /**
     * 获取redis中所有的key
     *
     * @return
     */
    private ArrayList<String> getKeys() {
        TopicLogMapper topicLogMapper = SpringUtils.getBean(TopicLogMapper.class);
        //  获取所有盒子
        List<TopicLog> topicLogs = topicLogMapper.getAllBox();
//        log.info(topicLogs.toString());
        TreeSet<String> boxName = new TreeSet<>(topicLogs.stream().map(TopicLog::getDeviceId).collect(Collectors.toList()));
        //  获取所有的key
        ArrayList<String> keys = new ArrayList<>();
        for (String logSet : boxName) {
            Set<String> tempKeys = redisTemplate.keys(logSet + ":*");
            if (tempKeys != null) {
                keys.addAll(tempKeys);
            }
        }
        return keys;
    }
}
